<script setup lang="ts">
import { Bottom, Delete, Finished, Plus, Top } from '@element-plus/icons-vue'
import { ElMessage, type FormInstance, type FormRules, type TabsPaneContext } from 'element-plus'
import { ref, reactive, onMounted, nextTick } from 'vue'
import EditTable from './editTable.vue'
import instance from '@/utils/serve'
import { getJueSeWeiHuApi } from '@/api/system'
const props = defineProps({
  isShow: {
    type: Boolean,
    default: false
  },
  fromInfo: {
    type: Object,
    default: () => {}
  }
})
const emit = defineEmits<{
  (e: 'update:isShow', value: boolean): void
  (e: 'saveSuccess'): void
}>()

const tableEdit = ref<any>()
const loading = ref(false)
const activedTab = ref('0') // 当前激活的tab
const tabClick = (tab: TabsPaneContext, event: Event) => {
  // console.log(tab.index)
  activedTab.value = tab.index as string
  if (activedTab.value == '0') return
  nextTick(() => {
    tableEdit.value.loadData([])
    loading.value = true
    instance
      .post('/common/getData', {
        dbName: 'report',
        sqlId: 'report.get' + tabs.value[activedTab.value].id,
        sqlParam: { report_id: form.value.report_id }
      })
      .then((res: any) => {
        loading.value = false
        tableEdit.value.loadData(res)
      })
  })
}
let require = (d: any, r: any, c: any) => !!d[c.prop] //非空
let unique = (d: any, r: any, c: any) =>
  !!d[c.prop] && !r.find((i: any) => i != d && i[c.prop] == d[c.prop])
const ruleFormRef = ref<any>()
const form = ref<any>({})

if (props.fromInfo) {
  form.value.report_id = props.fromInfo.report_id
}
// tabs数组
const tabs = ref<any>([
  { name: '基础信息' },
  {
    id: 'Dim',
    name: '查询维度',
    columns: [
      { prop: 'dim_name', label: '维度名称', width: 350, editor: { validator: require } },
      { prop: 'dim_field', label: '维度字段', 'min-width': 350, editor: { validator: unique } }
    ]
  },
  {
    id: 'Ind',
    name: '查询指标',
    columns: [
      { prop: 'ind_name', label: '指标名称', width: 350, editor: { validator: require } },
      { prop: 'ind_caliber', label: '指标口径', 'min-width': 350, editor: { validator: unique } }
    ]
  },
  {
    id: 'Cond',
    name: '查询条件',
    columns: [
      { prop: 'cond_name', label: '条件名称', 'min-width': 80, editor: { validator: require } },
      { prop: 'cond_field', label: '条件字段', 'min-width': 120, editor: { validator: unique } },
      {
        prop: 'dict_id',
        label: '数据字典',
        'min-width': 80,
        editor: {
          dict: null,
          onchange: (v: any, r: any) => {
            if (!v) {
              // this.$set(r, 'dict_id', null)
              // this.$set(r, 'multi_select', null) //无字典则无是否多选配置
              r.dict_id = null
              r.multi_select = null
            } else if (!r.multi_select) {
              // this.$set(r, 'multi_select', '0') //有字典默认单选配置
              r.multi_select = '0'
            }
          }
        }
      },
      {
        prop: 'dim_id',
        label: '维度配置',
        'min-width': 80,
        editor: {
          dict: null
          // onchange: (v: any, r: any) => {
          //   if (!v) {
          //     r.dict_id = null
          //     r.multi_select = '0'
          //   } else if (!r.multi_select) {
          //     r.multi_select = '0'
          //   }
          // }
        }
      },
      {
        prop: 'multi_select',
        label: '是否多选',
        width: 90,
        editor: {
          validator: (r: any) => {
            if (r.dict_id)
              return !!r.multi_select //有字典则必须有是否多选配置
            else return !r.multi_select //无字典则无是否多选配置
          },
          onchange: (v: any, r: any) => {
            if (!r.dict_id) r.multi_select = null // this.$set(r, 'multi_select', null) //无字典则无是否多选配置
          },
          dict: [
            { id: '1', name: '是' },
            { id: '0', name: '否' }
          ]
        }
      }
    ]
  }
])
// 表单校验规则
interface RuleForm {
  report_name: string
  table_name: string
  acct_field: string
  acct_type: string
  query_type: string
  db_name: string
  acct_format: string
  acct_custom_format: string
}
const formRules = reactive<FormRules<RuleForm>>({
  report_name: [{ required: true, message: '请输入报表名称' }],
  table_name: [
    { required: true, message: '请输入表名或查询结果集脚本' },
    {
      trigger: 'change',
      validator: (r, v, cb) => {
        const qt = form.value.query_type
        if (qt == 2) {
          if (/(insert|update|delete|truncate|drop|alter)\s+/.test(v))
            return cb(new Error('非法的统计语句！'))
          if (/\s*;\s*$/.test(v)) return cb(new Error('非法的统计语句！'))
        }
        return cb()
      }
    }
  ],
  acct_field: [{ required: true, message: '请输入账期列名' }],
  acct_type: [{ required: true, message: '请选择账期类型' }],
  query_type: [{ required: true, message: '请选择查询类型' }],
  db_name: [{ required: true, message: '请选择数据类型' }],
  acct_format: [{ required: true, message: '请输入账期格式' }],
  acct_custom_format: [{ required: true, message: '请输入自定义账期格式' }]
})

const initData = async () => {
  const params = {
    sqlId: 'dimMgr.dimInfo',
    sqlParam: JSON.stringify({ dimName: '' }),
    pagination: true,
    page: 1,
    rows: 100
  }
  await instance
    .post('/common/getData', { sqlId: 'dict.getSysDicts' })
    .then((res: any) => (tabs.value[3].columns[2].editor.dict = res))

  await getJueSeWeiHuApi(params).then(
    (res: any) =>
      (tabs.value[3].columns[3].editor.dict = res.rows.map((r: any) => ({
        id: r.dim_id,
        name: r.dim_name
      })))
  )
}

const show = (info: any) => {
  form.value = { ...info }
  activedTab.value = '0'
  emit('update:isShow', true)
  nextTick(() => ruleFormRef.value.clearValidate())
  // this.$nextTick(() => this.$refs.form.clearValidate());
}

// 保存
const saveForm = () => {
  // console.log(form.value)
  //  dbName: 'report',
  ruleFormRef.value.validate((valid: any) => {
    if (!valid) return
    loading.value = true
    instance
      .post('/reportConfig/saveConfig', { ...form.value, flag: 'save' })
      .then((res: any) => {
        loading.value = false
        if (res.code == 0) {
          ElMessage({ message: '保存成功', type: 'success' }) // this.$message.success("保存成功");
          form.value.report_id = res.message
          emit('saveSuccess')
        } else {
          ElMessage({ message: '保存失败', type: 'error' }) // this.$message.error('保存失败')
        }
      })
      .catch(() => ElMessage({ message: '保存失败', type: 'error' }))
      .finally(() => {
        loading.value = false
        emit('update:isShow', false)
      })
  })
}

// 保存
const saveList = () => {
  // console.log(tableEdit.value?.getChanges())
  if (!tableEdit.value?.getChanges()) return //编辑校验不通过
  let type = tabs.value[activedTab.value].id
  let sqlId = ['report.updateReport', 'report.del' + type, 'add' + type]
  if (type === 'Dim') sqlId = ['report.updateReport', 'report.del' + type, 'report.add' + type]

  let sqlParam = [
    { report_id: form.value.report_id },
    { report_id: form.value.report_id },
    tableEdit.value?.data.map((r: any, i: any) => ({ ...r, order_no: i + 1 }))
  ]
  loading.value = true
  instance.post('/common/modify', { dbName: 'report', sqlId, sqlParam }).then((res: any) => {
    loading.value = false
    if (res == 'success')
      ElMessage({ message: '保存成功', type: 'success' }) // this.$message.success('保存成功')
    else ElMessage({ message: '保存失败', type: 'error' }) // this.$message.error('保存失败')
  })
}
// 移动
const switchRow = (type: any) => {
  // console.log(info)
  // console.log(tableEdit.value)
  let row = tableEdit.value.editRow
  if (!row) return //无选中行
  let rows = tableEdit.value.data
  let idx1 = rows.indexOf(row)
  let idx2 = idx1 + type
  if (idx2 < 0 || idx2 >= rows.length) return
  rows.splice(idx1, 1)
  rows.splice(idx1 + type, 0, row)
}

const Cancel = (formEl: FormInstance) => {
  if (!formEl) return emit('update:isShow', false)
  formEl.resetFields()
  emit('update:isShow', false)
}

defineExpose({
  show
})

onMounted(() => {
  initData()
})
</script>
<template>
  <el-dialog width="70%" class="reportConfig" :model-value="isShow" @close="Cancel(ruleFormRef)">
    <div class="reportConfigBox" v-loading="loading">
      <el-tabs v-model="activedTab" @tab-click="tabClick">
        <el-tab-pane
          v-for="(t, i) in form.report_id ? tabs : [tabs[0]]"
          :key="i"
          :name="i + ''"
          :label="t.name"
        />
      </el-tabs>
      <div class="main">
        <el-form
          class="formBox"
          v-if="activedTab == '0'"
          ref="ruleFormRef"
          :model="form"
          :rules="formRules"
          label-width="100px"
        >
          <el-form-item label="报表名称" prop="report_name"
            ><el-input v-model="form.report_name" clearable
          /></el-form-item>
          <el-form-item label="查询类型" prop="query_type">
            <el-radio-group v-model="form.query_type">
              <el-radio :value="'1'">表名</el-radio>
              <el-radio :value="'2'">结果集脚本</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="数据源" prop="db_name">
            <el-radio-group v-model="form.db_name">
              <el-radio :value="'doris'">doris</el-radio>
              <el-radio :value="'report'">report</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="查询表名" prop="table_name" v-if="form.query_type == 1"
            ><el-input v-model="form.table_name" clearable
          /></el-form-item>
          <el-form-item label="结果集脚本" prop="table_name" v-else>
            <el-input
              type="textarea"
              :autosize="{ minRows: 4, maxRows: 4 }"
              placeholder="请输入表名或查询结果集脚本"
              v-model="form.table_name"
            ></el-input>
          </el-form-item>
          <el-form-item label="账期列名" prop="acct_field"
            ><el-input v-model="form.acct_field" clearable
          /></el-form-item>
          <el-form-item label="账期类型" prop="acct_type">
            <el-radio-group v-model="form.acct_type">
              <el-radio :value="'1'">时段</el-radio>
              <el-radio :value="'2'">时点</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="账期格式" prop="acct_format">
            <el-radio-group v-model="form.acct_format">
              <el-radio :value="'1'">日</el-radio>
              <el-radio :value="'2'">月</el-radio>
              <el-radio :value="'3'">自定义</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="自定义格式" prop="acct_custom_format" v-if="form.acct_format == 3"
            ><el-input v-model="form.acct_custom_format" clearable
          /></el-form-item>
          <el-form-item>
            <el-button :icon="Finished" type="primary" @click="saveForm">保存</el-button>
          </el-form-item>
        </el-form>
        <div v-else class="table-box d-flex flex-column h-100">
          <div style="margin-bottom: 15px">
            <el-button
              :icon="Plus"
              type="success"
              @click="tableEdit.addRow({ report_id: form.report_id })"
              plain
            >
              新增
            </el-button>
            <el-button :icon="Top" type="primary" @click="switchRow(-1)">上移</el-button>
            <el-button :icon="Bottom" type="primary" @click="switchRow(1)">下移</el-button>
            <el-button :icon="Delete" type="danger" @click="tableEdit.removeSelected()">
              删除
            </el-button>
            <el-button :icon="Finished" type="primary" @click="saveList">保存</el-button>
          </div>
          <EditTable ref="tableEdit" :columns="tabs[activedTab].columns" />
          <!-- <edit-table ref="table" :columns="tabs[activedTab].columns" /> -->
        </div>
      </div>
    </div>
  </el-dialog>
</template>
<style scoped lang="less">
.reportConfigBox {
  // height: calc(80vh - 95px);
  :deep(.el-tabs__nav.is-top) {
    .el-tabs__item.is-top {
      align-items: start;
      height: 34px;
    }
    .el-tabs__item.is-top:nth-child(2) {
      padding-left: 20px !important;
    }
    .el-tabs__active-bar {
      padding: 0 20px !important;
    }
  }
  .el-dialog__headerbtn {
    z-index: 999;
  }
  .el-tabs {
    padding: 0 20px;
  }
  .el-dialog__body {
    padding: 0;
    margin-top: -18px;
  }
}
.main {
  padding: 0 20px;
  overflow: auto;
  .formBox {
    margin-top: 30px;
  }
}
</style>
